﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using MoneyWentWhere.DataModel.Binding;
using System.Collections;
using MoneyWentWhere.DataModel.Tx;
using System.Text.RegularExpressions;

namespace MoneyWentWhere.DataModel
{
    [TypeConverter(typeof(TxSettingsTypeConverter))]
    public abstract class TxSettings
    {
        public const String TransferPrefix = "@";
        public const String ReconcilePrefix = "Reconcile";

        public abstract TransactionKind Kind { get; }

        public static TxSettings Parse(String rep)
        {
            if (rep.StartsWith(ReconcilePrefix, StringComparison.InvariantCultureIgnoreCase))
            {
                return ReconcileTxSettings.Parse(rep);
            }
            else if (rep.StartsWith(TransferPrefix))
            {
                return TransferTxSettings.Parse(rep);
            }
            else
            {
                return NormalTxSettings.Parse(rep);
            }
        }
        public abstract String ToRepString();

        internal static TxSettings Create(Transaction t)
        {
            switch (t.Kind)
            {
                case TransactionKind.Reconcile: return ReconcileTxSettings.Create(t);
                case TransactionKind.Transfer: return TransferTxSettings.Create(t);
                case TransactionKind.Normal: return NormalTxSettings.Create(t);
                default: throw new InvalidOperationException("Unknown: " + t.Kind);
            }
        }
        internal void Apply(Transaction t)
        {
            t.Kind = Kind;
            ApplyCore(t);
        }
        protected abstract void ApplyCore(Transaction t);


        #region Helpers
        internal static int IndexOfMinLengthItem(IList list, out int minLength)
        {
            minLength = int.MaxValue;
            int index = -1;
            for (int i = 0; i < list.Count; i++)
            {
                String item;
                if (list[i] is Account) { item = ((Account)list[i]).Name; }
                else { item = (String)list[i]; }

                int len = item.Length;
                if (len < minLength)
                {
                    index = i;
                    minLength = len;
                }
            }
            return index;
        }

        internal static bool TryExtractNumber(String str, out decimal value)
        {
            value = 0;
            Match m = Regex.Match(str, @"[0-9,.]+");
            if (m.Groups.Count == 0) { return false; }
            return decimal.TryParse(m.Groups[0].Value, out value);
        }

        #endregion 
    }
}
